﻿// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Xml.Linq;
using Microsoft.Windows.Design.Metadata;

namespace Expression.Samples.Interactivity.Design {
	public static class DescriptionLoader {
		/// <summary>
		/// Simple parser to provide descriptions and text to all of the type and properties.
		/// This just parses the XML intellisense file and pulls them from there. Quick and dirty :)
		/// </summary>
		/// <param name="assembly"></param>
		/// <param name="builder"></param>
		public static void LoadComments(Assembly assembly, AttributeTableBuilder builder, string commentsFile) {

			string assemblyName = typeof(DescriptionLoader).Assembly.FullName.Split(',')[0];
			ResourceManager resourceManager = new ResourceManager(assemblyName + ".g", typeof(DescriptionLoader).Assembly);

			Stream stream = resourceManager.GetStream(commentsFile.ToLower());
			StreamReader streamReader = new StreamReader(stream);

			XDocument document = XDocument.Load(streamReader);

			foreach (XElement member in document.Elements("doc").Elements("members").Elements("member")) {
				string name = member.Attribute("name").Value;

				string[] directives = name.Split(':');
				char commentType = directives[0][0];
				string summary = member.Element("summary").Value.Trim();

				switch (commentType) {
					case 'F': {
							string typeName = directives[1].Substring(0, directives[1].LastIndexOf('.'));
							string fieldName = directives[1].Substring(directives[1].LastIndexOf('.') + 1);
							Type type = assembly.GetType(typeName);
							if (type != null) {
								FieldInfo field = type.GetField(fieldName);
								if (field != null) {
									builder.AddCustomAttributes(type, fieldName, new DescriptionAttribute(summary));
								}
							}
						}
						break;
					case 'T': {
							Type type = assembly.GetType(directives[1]);
							if (type != null)
								builder.AddCustomAttributes(type, new DescriptionAttribute(summary));
						}
						break;
					case 'M':
						// Don't care about methods.
						break;
					case 'P': {
							string typeName = directives[1].Substring(0, directives[1].LastIndexOf('.'));
							string propertyName = directives[1].Substring(directives[1].LastIndexOf('.') + 1);
							Type type = assembly.GetType(typeName);
							if (type != null) {
								PropertyInfo field = type.GetProperty(propertyName);
								if (field != null) {
									builder.AddCustomAttributes(type, propertyName, new DescriptionAttribute(summary));
								}
							}
						}
						break;
					default:
						break;
				}

			}

		}
	}
}
